using System.CodeDom;
using System.Collections.Generic;

namespace BDDfyIt.CodeDom
{
    public class CodeClass : CodeTypeDeclaration
    {
        private CodeTypeDeclaration _class;

        public new string Name
        {
            get { return base.Name; }
            set { base.Name = value; }
        }

        public string AccessModifier
        {
            get
            {
                return _class.Attributes.ToString();
            }
            set
            {
                _class.Attributes = Extensions.ParseEnum(value, MemberAttributes.Public);
            }
        }

        public List<CodeMemberMethod> Methods
        {
            get { return GetCodeMemberMethods(_class.Members); }
            set
            {
                var members = GetCodeTypeMemberCollection(value);
                if (members != null)
                {
                    _class.Members.AddRange(members);
                }
            }
        }

        public List<CodeMemberProperty> Properties
        {
            get { return GetCodeMemberProperties(_class.Members); }
            set
            {
                var members = GetCodeTypeMemberCollection(value);
                if (members != null)
                {
                    _class.Members.AddRange(members);
                }
            }
        }

        public List<CodeMemberField> Fields
        {
            get { return GetCodeMemberFields(_class.Members); }
            set
            {
                var members = GetCodeTypeMemberCollection(value);
                if (members != null)
                {
                    _class.Members.AddRange(members);
                }
            }
        }

        public CodeClass()
        {
            _class = new CodeTypeDeclaration();
            IsClass = true;
        }

        public void AddMethods(List<CodeMemberMethod> methods)
        {
            var members = GetCodeTypeMemberCollection(methods);
            if (members != null)
            {
                _class.Members.AddRange(members);
            }
        }

        private List<CodeMemberMethod> GetCodeMemberMethods(CodeTypeMemberCollection members)
        {
            if (members == null)
            {
                return null;
            }
            var membersList = new List<CodeMemberMethod>();

            foreach (var member in members)
            {
                var m = member as CodeMemberMethod;
                membersList.Add(m);
            }
            return membersList;
        }

        private CodeTypeMemberCollection GetCodeTypeMemberCollection(List<CodeMemberMethod> methodsList)
        {
            if (methodsList == null)
            {
                return null;
            }
            var members = new CodeTypeMemberCollection();
            foreach (var method in methodsList)
            {
                members.Add(method);
            }
            return members;
        }

        private List<CodeMemberProperty> GetCodeMemberProperties(CodeTypeMemberCollection members)
        {
            if (members == null)
            {
                return null;
            }
            var propertiesList = new List<CodeMemberProperty>();

            foreach (var member in members)
            {
                var property = member as CodeMemberProperty;
                propertiesList.Add(property);
            }
            return propertiesList;
        }

        private CodeTypeMemberCollection GetCodeTypeMemberCollection(List<CodeMemberProperty> propertiesList)
        {
            if (propertiesList == null)
            {
                return null;
            }
            var members = new CodeTypeMemberCollection();
            foreach (var member in propertiesList)
            {
                members.Add(member);
            }
            return members;
        }

        private List<CodeMemberField> GetCodeMemberFields(CodeTypeMemberCollection members)
        {
            if (members == null)
            {
                return null;
            }
            var fieldsList = new List<CodeMemberField>();

            foreach (var member in members)
            {
                var m = member as CodeMemberField;
                fieldsList.Add(m);
            }
            return fieldsList;
        }

        private CodeTypeMemberCollection GetCodeTypeMemberCollection(List<CodeMemberField> fieldsList)
        {
            if (fieldsList == null)
            {
                return null;
            }
            var members = new CodeTypeMemberCollection();
            foreach (var member in fieldsList)
            {
                members.Add(member);
            }
            return members;
        }
    }
}